// 切片
package slices

import (
	"fmt"
	"strings"
)

// Index 返回下标
func Index[T comparable](s []T, v T) int {
	for i, sv := range s {
		if v == sv {
			return i
		}
	}
	return -1
}

// In 检测是否存在
func In[T comparable](s []T, key T) bool {
	// 处理
	for _, v := range s {
		if v == key {
			return true
		}
	}

	// 返回
	return false
}

// Contains 是否包含
func Contains[T comparable](s []T, v T) bool {
	return Index(s, v) >= 0
}

// Diff 差集
func Diff[T comparable](s []T, s2 []T) (r []T) {
	// map[string]struct{}{}创建了一个key类型为String值类型为空struct的map，Equal -> make(map[string]struct{})
	temp := map[T]struct{}{}

	for _, val := range s2 {
		if _, ok := temp[val]; !ok {
			temp[val] = struct{}{} // 空struct 不占内存空间
		}
	}

	for _, val := range s {
		if _, ok := temp[val]; !ok {
			r = append(r, val)
		}
	}

	return
}

// Unique 去重
func Unique[T comparable](s []T) (r []T) {
	for _, i := range s {
		if !Contains(r, i) {
			r = append(r, i)
		}
	}
	return
}

// Merge 合并
func Merge[T comparable](s, s2 []T, isUnique bool) (r []T) {
	// 循环组装
	r = append(r, s...)
	r = append(r, s2...)

	// 去重
	if isUnique {
		r = Unique(r)
	}

	// 返回
	return
}

// ToString 转字符串
func ToString[T comparable](s []T, sep string) (r string) {
	// 结果
	var result string

	// 处理
	for _, v := range s {
		result += fmt.Sprintf("%v", v) + sep
	}

	// 返回
	r = strings.TrimRight(result, sep)
	return
}
